###############################################################################
# Name: KTaskReport.py                                                        #
# Author: Marijo Mihelcic <marijo.mihelcic@gmail.com>                         #
# Copyright: (c) 2009 Marijo Mihelcic <marijo.mihelcic@gmail.com>             #
# Licence: GNU General Public License v3                                      #
###############################################################################

from PyQt4 import QtCore, QtGui
from gui import KTaskTimerReportUI
from lib import KTaskTimerDB
import datetime
import time


class TaskReportDialog(QtGui.QMainWindow):
    def __init__(self, parent):
        #QtGui.QDialog.__init__(self, parent)
        QtGui.QWidget.__init__(self, parent)

        # Set up the user interface from Designer.
        self.ui = KTaskTimerReportUI.Ui_TaskTimerReports()
        self.ui.setupUi(self)

        """ data source """
        self.dataSource = KTaskTimerDB.DataSource()

        """ set dates """
        current_date = QtCore.QDate.currentDate()
        self.ui.dateFrom.setDate(current_date)
        self.ui.dateTo.setDate(current_date)

        self._populateProjects()

        """ Generate report """
        self.connect(self.ui.generateReport, QtCore.SIGNAL("clicked()"), self.generateReport)

        """ Close program """
        self.connect(self.ui.actionClose, QtCore.SIGNAL("triggered()"), self, QtCore.SLOT("close()"))

        """ Save as """
        self.ui.actionSave_as.setEnabled(False)
        self.connect(self.ui.actionSave_as, QtCore.SIGNAL("triggered()"), self.saveAsDialog)


    def _populateProjects(self):
        projects_list_data = self.dataSource.getProjectsLists()

        """ Projects sorting """
        projects_sorted = projects_list_data.items()
        projects_sorted.sort(key=lambda x: x[1])

        """ Populating data """
        self.ui.projectList.addItem('All projects',QtCore.QVariant(None))
        for project_data in projects_sorted:
            self.ui.projectList.addItem(project_data[1],QtCore.QVariant(project_data[0]))

    def saveAsDialog(self):
        fileName = QtGui.QFileDialog.getSaveFileName(self,
                                         self.tr("Save report as"),
                                         '',
                                         self.tr("CSV (*.csv);;Microsoft Excel XML (*.xml)"))

        if fileName.isEmpty():
            return False

        if (fileName.endsWith('xml', QtCore.Qt.CaseInsensitive)):
            report_data = self._saveXMLFile()
        else:
            report_data = self._saveCSVFile()

        self._storeFile(fileName, report_data)


    def _storeFile(self, fileName, fileData):

        file = QtCore.QFile(fileName)
        if not file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text):
            QtGui.QMessageBox.warning(self, self.tr("Application"),
                        self.tr("Cannot write file %1:\n%2.").arg(fileName).arg(file.errorString()))
            return False

        outf = QtCore.QTextStream(file)
        outf.setCodec("UTF-8");
        QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor)
        outf << fileData
        QtGui.QApplication.restoreOverrideCursor()

    def _saveCSVFile(self):
        save_data   = self.dataSource.getReports({"project_id": self.project_id, "date_from": self.date_from, "date_to": self.date_to})
        out_string  = ''

        for project_id in save_data.keys():
            for task_id in save_data[project_id]['tasks'].keys():
                for task_progress_id in save_data[project_id]['tasks'][task_id]["task_progress"].keys():
                    out_string +=   save_data[project_id]['title'] + '\t'
                    out_string +=   save_data[project_id]["tasks"][task_id]['title'] + '\t'
                    out_string +=   save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["description"].replace("\n", ' ') + '\t'
                    out_string +=   str(save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["time_worked"]) + '\t'
                    out_string +=   str(save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["start_date"]) + '\t'
                    out_string +=   str(save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["end_date"])
                    out_string +=   "\n"

        return out_string


    def _saveXMLFile(self):
        save_data = self.dataSource.getReports({"project_id": self.project_id, "date_from": self.date_from, "date_to": self.date_to})
        header = """<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?>
<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:o="urn:schemas-microsoft-com:office:office"
    xmlns:x="urn:schemas-microsoft-com:office:excel"
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:html="http://www.w3.org/TR/REC-html40">
    <OfficeDocumentSettings xmlns="urn:schemas-microsoft-com:office:office">
        <DownloadComponents/>
        <LocationOfComponents HRef="file:///\"/>
    </OfficeDocumentSettings>
    <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
        <ActiveSheet>0</ActiveSheet>
        <ProtectStructure>False</ProtectStructure>
        <ProtectWindows>False</ProtectWindows>
    </ExcelWorkbook>
    <Styles>
        <Style ss:ID="Default" ss:Name="Normal">
            <Alignment ss:Vertical="Bottom"/>
            <Borders/>
            <Font/>
            <Interior/>
            <NumberFormat/>
            <Protection/>
        </Style>
        <Style ss:ID="bold">
            <Font ss:Bold="1" />
        </Style>
        <Style ss:ID="header">
            <Interior ss:Pattern="Solid" ss:Color="#F0F0F0" />
            <Font ss:Bold="1" ss:Size="12" ss:Color="#000000" />
        </Style>
    </Styles>
    <Worksheet ss:Name="Reports">
        """

        footer = """        <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
            <ProtectObjects>False</ProtectObjects>
            <ProtectScenarios>False</ProtectScenarios>
        </WorksheetOptions>
    </Worksheet>
</Workbook>"""

        out_string  = ''
        rows_cnt    = 1

        for project_id in save_data.keys():
            for task_id in save_data[project_id]['tasks'].keys():
                for task_progress_id in save_data[project_id]['tasks'][task_id]["task_progress"].keys():
                    rows_cnt+= 1
                    out_string += "            <Row>\n"
                    out_string +=   '                <Cell><Data ss:Type="String">' + save_data[project_id]['title'] + "</Data></Cell>\n"
                    out_string +=   '                <Cell><Data ss:Type="String">' + save_data[project_id]["tasks"][task_id]['title'] + "</Data></Cell>\n"
                    out_string +=   '                <Cell><Data ss:Type="String">' + save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["description"] + "</Data></Cell>\n"
                    out_string +=   '                <Cell><Data ss:Type="Number">' + str(save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["time_worked"]) + "</Data></Cell>\n"
                    out_string +=   '                <Cell><Data ss:Type="String">' + str(save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["start_date"]) + "</Data></Cell>\n"
                    out_string +=   '                <Cell><Data ss:Type="String">' + str(save_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["end_date"]) + "</Data></Cell>\n"
                    out_string +=   "            </Row>\n"

        out_string +=   "        </Table>\n"
        table_head      = '<Table ss:ExpandedColumnCount="6" ss:ExpandedRowCount="' + str(rows_cnt) + '" x:FullColumns="1" x:FullRows="1">'
        table_columns   = """
            <Column ss:Index="1" ss:Width="150" />
            <Column ss:Index="2" ss:Width="150" />
            <Column ss:Index="3" ss:Width="150" />
            <Column ss:Index="4" ss:Width="70" />
            <Column ss:Index="5" ss:Width="150" />
            <Column ss:Index="6" ss:Width="150" />
            <Row>
                <Cell ss:StyleID="header"><Data ss:Type="String">Project</Data></Cell>
                <Cell ss:StyleID="header"><Data ss:Type="String">Task</Data></Cell>
                <Cell ss:StyleID="header"><Data ss:Type="String">Task progress</Data></Cell>
                <Cell ss:StyleID="header"><Data ss:Type="String">Duration (min)</Data></Cell>
                <Cell ss:StyleID="header"><Data ss:Type="String">Start date</Data></Cell>
                <Cell ss:StyleID="header"><Data ss:Type="String">End date</Data></Cell>
            </Row>
"""
        save_str = header + table_head + table_columns + out_string + footer
        return save_str

    def generateReport(self):
        current_item            = self.ui.projectList.currentIndex()
        selected_project_data   = self.ui.projectList.itemData(current_item).toInt()
        if selected_project_data[0] == 0 and selected_project_data[1] == False:
            self.project_id = None
        else:
            self.project_id = selected_project_data[0]

        datetime_from   = self.ui.dateFrom.date().toString(QtCore.Qt.ISODate)
        datetime_to     = self.ui.dateTo.date().toString(QtCore.Qt.ISODate)

        self.date_from   = datetime.date(*time.strptime(str(datetime_from), "%Y-%m-%d")[0:3])
        self.date_to     = datetime.date(*time.strptime(str(datetime_to), "%Y-%m-%d")[0:3])
        self.date_to     += datetime.timedelta(days=+1)

        self.formatReport(self.dataSource.getReports({"project_id": self.project_id, "date_from": self.date_from, "date_to": self.date_to}))
        self.ui.actionSave_as.setEnabled(True)

    def formatReport(self, task_progress_data):
        out_string          = ''
        project_duration    = 0
        task_duration       = 0

        self.ui.reportTree.clear()

        for project_id in task_progress_data.keys():
            for task_id in task_progress_data[project_id]['tasks'].keys():
                for task_progress_id in task_progress_data[project_id]['tasks'][task_id]["task_progress"].keys():
                    item=QtGui.QTreeWidgetItem([
                        task_progress_data[project_id]['title'],
                        task_progress_data[project_id]["tasks"][task_id]['title'],
                        task_progress_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["description"],
                        str(task_progress_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["time_worked"]),
                        str(task_progress_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["start_date"]),
                        str(task_progress_data[project_id]['tasks'][task_id]["task_progress"][task_progress_id]["end_date"])
                    ]
                    )
                    item.setFlags(QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsEnabled)
                    self.ui.reportTree.addTopLevelItem(item)